package com.leidi.javacallspython.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.leidi.javacallspython.enetity.Fqa;
import com.leidi.javacallspython.enetity.Train;
import com.leidi.javacallspython.enetity.vo.QstAnsVo;
import com.leidi.javacallspython.mapper.QstAnsMapper;
import com.leidi.javacallspython.service.CallPythonService;
import com.leidi.javacallspython.service.IFqaService;
import com.leidi.javacallspython.service.ITrainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class CallPythonServiceImpl implements CallPythonService {

  private static Logger logger = LoggerFactory.getLogger(CallPythonServiceImpl.class);

  @Value("${leidi.python.path}")
  private String pythonPath;

  @Value("${leidi.python.script.training}")
  private String pythonScriptTraining;

  @Value("${leidi.python.script.prepareDataset}")
  private String pythonScriptPrepareDataset;

  @Value("${leidi.python.script.predict}")
  private String pythonScriptPredict;

  @Autowired
  private IFqaService fqaService;
  @Autowired
  private ITrainService trainService;
  @Autowired
  private QstAnsMapper qstAnsMapper;

  @Override
  public String training() {
    String[] args = new String[] {pythonPath, pythonScriptTraining};
    return execPythonScript(args);
  }

  @Override
  public String saveDatasetTxt(String questions, String answer) {
    String[] args = new String[] {pythonPath, pythonScriptPrepareDataset, questions, answer};
    return execPythonScript(args);
  }

  @Override
  public String autoQA(String questions) {
    String[] args = new String[] {pythonPath, pythonScriptPredict, questions};
    return execPythonScript(args);
  }

  @Override
  public String saveDataset(QstAnsVo qstAnsVo) {
    boolean bl = false;
    if (null != qstAnsVo) {
      Fqa fqa = new Fqa();
      if (qstAnsVo.getFqaFqaId() != null){
        fqa.setId(qstAnsVo.getFqaFqaId());
      }
      fqa.setAnswer(qstAnsVo.getAnswer());
      bl = fqaService.saveOrUpdate(fqa);
      BigInteger fqaId = fqa.getId();
      List<Train> trains = qstAnsVo.getTrain();
      for (Train train : trains) {
        train.setFqaId(fqaId);
        bl = trainService.saveOrUpdate(train);
      }
    }
    if (bl) {
      return "存入成功";
    }
    return "存入失败！";
  }

//  @Override
//  public List<QstAnsVo> selectQa(String question) {
//    List<QstAnsVo> list = new ArrayList<>();
//    Set<BigInteger> fqaIds = new HashSet<>();
//    String limit = String.format("limit %s,%s", pageNum, pageSize);
//    List<Train> trains =
//        trainService.list(
//            new QueryWrapper<Train>().like(StringUtils.isNotBlank(question), "question", question));
//    if (!CollectionUtils.isEmpty(trains)) {
//      for (Train train : trains) {
//        fqaIds.add(train.getFqaId());
//      }
//    }
//    if (!CollectionUtils.isEmpty(fqaIds)) {
//      for (BigInteger fqaId : fqaIds) {
//        QstAnsVo qstAnsVo = new QstAnsVo();
//        List<Train> trainList =
//            trainService.list(new QueryWrapper<Train>().eq("fqa_id", fqaId));
//        Fqa fqa = fqaService.getById(fqaId);
//        qstAnsVo.setTrain(trainList);
//        qstAnsVo.setFqa(fqa);
//        list.add(qstAnsVo);
//      }
//    }
//    return list;
//  }
  @Override
  public List<QstAnsVo> selectQa(String question) {
    return qstAnsMapper.selectList(question);
  }

  @Override
  public boolean deleteByIds(BigInteger[] answerIds) {
    List<Train> trains =
        trainService.list(
            new QueryWrapper<Train>()
                .in(
                    !CollectionUtils.isEmpty(Arrays.asList(answerIds)),
                    "fqa_id",
                    Arrays.asList(answerIds)));
    List<BigInteger> trainId = trains.stream().map(Train::getId).collect(Collectors.toList());
    boolean bl = fqaService.removeByIds(Arrays.asList(answerIds));
    if (bl) {
      return trainService.removeByIds(trainId);
    }
    return false;
  }

  @Override
  public String prepare() {
    String[] args = new String[] {pythonPath, pythonScriptPrepareDataset};
    return execPythonScript(args);
  }

  @Override
  public String parsingDocunment(MultipartFile files) {
    logger.info("正在解析文档...");
    StringBuilder result = new StringBuilder();
    try {
      BufferedReader br = new BufferedReader(new InputStreamReader(files.getInputStream(), "UTF-8"));//构造一个BufferedReader类来读取文件
      String s = null;
      while((s = br.readLine())!=null){//使用readLine方法，一次读一行
        result.append(s);
      }
      br.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return result.toString();
  }

  private String execPythonScript(String[] args) {
    logger.info(Arrays.toString(args));
    Process proc;
    String result = null;
    try {
      proc = Runtime.getRuntime().exec(args); // 执行py文件
      // 用输入输出流来截取结果
      BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream(), "gbk"));
      //      BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream(),
      // StandardCharsets.UTF_8));//linux乱码
      String line;
      while ((line = in.readLine()) != null) {
        logger.info(line);
        result = line;
      }
      in.close();
      proc.waitFor();
    } catch (IOException | InterruptedException e) {
      e.printStackTrace();
    }
    return result;
  }
}
